home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 109_01.zip / WP.C < prev    next >
Text File  |  1993-06-26  |  9KB  |  516 lines

  1. /*
  2.     Word processor
  3.     Translated from the 'format' program in 'Software Tools'
  4. */
  5.  
  6. #include <macdefs.wp>
  7. #include <globals.wp>
  8.  
  9. #define fputc putc    /* I keep getting it wrong */
  10.  
  11.  
  12.  
  13. /*
  14.     Initialize global variables
  15. */
  16.  
  17.  
  18. initialize()
  19.     {
  20.     lineno = curpag = 0;
  21.     newpag = 1;
  22.     plval = PAGELEN;
  23.     m1val = m2val = m3val = m4val = 2;
  24.     bottom = plval - m3val - m4val;
  25.     strcpy(header,"\n");
  26.     strcpy(footer,"\n");
  27.     *outbuf = '\0';        /* initially empty output buffer */
  28.  
  29.     fill = YES;
  30.     lsval = 1;
  31.     rmval = PAGEWIDTH;
  32.     inval = tival = ceval = ulval = 0;
  33.  
  34.     outp = outw = outwds = 0;
  35.  
  36.     dir = 0;
  37.     }
  38.  
  39.  
  40. /*
  41.     Word processing main program
  42. */
  43.  
  44. main(argc,argv)
  45.     int argc;
  46.     char *argv[];
  47.     {
  48.     char *fgets();
  49.     char ifile[134];
  50.     char ofile[134];
  51.     int ofd;
  52.     char inbuf[INSIZE];    /* input line buffer */
  53.  
  54.     if( argc != 3 )
  55.       exit(puts("\nusage: WP <infile> <outfile>"));
  56.     if( fopen(argv[1],ifile) == NOFILE )
  57.       exit(printf("\nNo such file : %s",argv[1]));
  58.     if( samestr(argv[2],"CON:") )
  59.       outfile = 1;
  60.     else if( samestr(argv[2],"LST:") )
  61.       outfile = 2;
  62.     else if( samestr(argv[2],"PUN:") )
  63.       outfile = 3;
  64.     else {    /* output sent to disk */
  65.       if( (ofd = fcreat(argv[2],ofile)) == NOFILE )
  66.         exit(printf("\nCan't open : %s",argv[2]));
  67.       else
  68.         outfile = ofile;
  69.       }
  70.     initialize();
  71.     while( fgets(inbuf,ifile) ) {
  72.       xpndtab(inbuf);
  73.       if( inbuf[0] == COMMAND )
  74.         command(inbuf);
  75.       else
  76.         text(inbuf);
  77.       }
  78.     brk();            /* flush any remaining text */
  79.     if( lineno > 0 )
  80.       space(HUGE);
  81.     if( outfile == 2 ) /* lineprinter */
  82.       fputc('\f',outfile);
  83.     else if( outfile > 3 ) { /* diskfile */
  84.       fputc(0x1a,outfile);
  85.       fflush(outfile);
  86.       if( close(ofd) == NOFILE )
  87.       printf("\nCan't close : %s",argv[2]);
  88.       }
  89.     }
  90.  
  91.  
  92.  
  93.  
  94. /*
  95.     Command handler
  96.  
  97.     Defined commands:
  98.  
  99.     BP    .bp    {+,-} {<n>}    * begin page and set page number
  100.     BR    .br            * break
  101.     CE    .ce    {<n>}        * center n lines (default 1)
  102.     FI    .fi            * fill
  103.     FO    .fo    {<text>}      footer title
  104.     HE    .he    {<text>}      header title
  105.     IN    .in    {+,-}<n>      indent n co
  106.     LS    .ls    {+,-}<n>      line spacing
  107.     NF    .nf            * no fill
  108.     PL    .pl    {+,-}<n>      page length of n lines
  109.     RM    .rm    {+,-}<n>      right margin n columns
  110.     SP    .sp    {<n>}        * space n lines (default 1 )
  111.     TI    .ti    {+.-}<n>    * temporary indent n columns
  112.     UL    .ul    {<n>}          underline n lines (default 1)
  113.  
  114.     note: * => causes a break
  115.  
  116. */
  117.  
  118. command(buf)
  119.     char *buf;
  120.     {
  121.     int comtyp(),getval(),max();
  122.     char argtyp;
  123.     int ct;
  124.     int spval;
  125.     int val;
  126.  
  127.     val = getval(buf,&argtyp);
  128.     switch( ct = comtyp(buf) ) {
  129.       case BP:    if( lineno > 0 )
  130.               space(HUGE);
  131.             set(&curpag,val,argtyp,curpag+1,-HUGE,HUGE);
  132.             newpag = curpag;
  133.             break;
  134.  
  135.       case BR:    brk();
  136.             break;
  137.  
  138.       case CE:    brk();
  139.             set(&ceval,val,argtyp,1,0,HUGE);
  140.             break;
  141.  
  142.       case FI:    brk();
  143.             fill = YES;
  144.             break;
  145.  
  146.       case FO:    gettl(buf,footer);
  147.             break;
  148.  
  149.       case HE:    gettl(buf,header);
  150.             break;
  151.  
  152.       case IN:    set(&inval,val,argtyp,0,0,rmval-1);
  153.             tival = inval;
  154.             break;
  155.  
  156.       case LS:    set(&lsval,val,argtyp,1,1,HUGE);
  157.             break;
  158.  
  159.       case NF:    brk();
  160.             fill = NO;
  161.             break;
  162.  
  163.       case PL:    set(&plval,val,argtyp,PAGELEN,
  164.                 (m1val+m2val+m3val+m4val+1),HUGE);
  165.             bottom = plval - m3val - m4val;
  166.             break;
  167.  
  168.       case RM:    set(&rmval,val,argtyp,PAGEWIDTH,tival+1,HUGE);
  169.             break;
  170.  
  171.       case SP:    set(&spval,val,argtyp,1,0,HUGE);
  172.             space(spval);
  173.             break;
  174.  
  175.       case TI:    brk();
  176.             set(&tival,val,argtyp,0,0,rmval);
  177.             break;
  178.  
  179.       case UL:    set(&ulval,val,argtyp,0,1,HUGE);
  180.             break;
  181.  
  182.       default:    break;    /* ignore unknown commands */
  183.       }
  184.     }
  185.  
  186. /*
  187.     process Text
  188. */
  189.  
  190. text(inbuf)
  191.     char inbuf[];
  192.     {
  193.     int i;
  194.  
  195.     if( inbuf[0] == ' ' || inbuf[0] == '\n' )
  196.       leadbl(inbuf);
  197.     if( ulval > 0 )    {        /* underlining */
  198.       underl(inbuf,wrdbuf,INSIZE);
  199.       ulval--;
  200.       }
  201.     if( ceval > 0 )    {        /* centering in effect */
  202.       center(inbuf);
  203.       put(inbuf);
  204.       ceval--;
  205.       }
  206.     else if( inbuf[0] == '\n' )    /* all blank line */
  207.       put(inbuf);
  208.     else if( fill == NO )        /* un-filled text */
  209.       put(inbuf);
  210.     else                /* filled text */
  211.       for( i=0; getwrd(inbuf,&i,wrdbuf) > 0; )
  212.         putwrd(wrdbuf);
  213.     }
  214.  
  215.  
  216.  
  217. /*
  218.     Command type
  219. */
  220.  
  221.  
  222. comtyp(buf)
  223.     char *buf;
  224.     {
  225.     int index();
  226.     char cmd[2];
  227.     int i;
  228.  
  229.     for(i=0; i < 2;    i++ )
  230.       cmd[i] = tolower(buf[i+1]);
  231.     cmd[2] = '\0';
  232.     if( samestr(cmd,"bp") )
  233.       return BP;
  234.     else if( samestr(cmd,"br") )
  235.       return BR;
  236.     else if( samestr(cmd,"ce") )
  237.       return CE;
  238.     else if( samestr(cmd,"fi") )
  239.       return FI;
  240.     else if( samestr(cmd,"fo") )
  241.       return FO;
  242.     else if( samestr(cmd,"he") )
  243.       return HE;
  244.     else if( samestr(cmd,"in") )
  245.       return IN;
  246.     else if( samestr(cmd,"ls") )
  247.       return LS;
  248.     else if( samestr(cmd,"nf") )
  249.       return NF;
  250.     else if( samestr(cmd,"pl") )
  251.       return PL;
  252.     else if( samestr(cmd,"rm") )
  253.       return RM;
  254.     else if( samestr(cmd,"sp") )
  255.       return SP;
  256.     else if( samestr(cmd,"ti") )
  257.       return TI;
  258.     else if( samestr(cmd,"ul") )
  259.       return UL;
  260.     else
  261.       return UNKNOWN;
  262.     }
  263.  
  264.  
  265.  
  266. /*
  267.     Get a parameter value from a command line
  268.     and whether it is an absolute or relative value
  269. */
  270.  
  271. getval(buf,argtyp)
  272.     char *buf;
  273.     char *argtyp;    /* pointer to single char */
  274.     {
  275.     int abs(),atoi();
  276.  
  277.     while( ! isspace(*buf) )    /* skip command */
  278.       buf++;
  279.     while( isspace(*buf) )        /* skip whitespace separator */
  280.       buf++;
  281.     *argtyp = *buf;            /* argument type: +, - or digit    */
  282.     if( isdigit(*argtyp) )
  283.       *argtyp = '0';
  284.     if( *argtyp == '+' )
  285.       ++buf;
  286.     return abs(atoi(buf));
  287.     }
  288.  
  289.  
  290.  
  291. /*
  292.     Set parameter and saturate on out of valid range
  293. */
  294.  
  295. set(param,val,argtyp,defval,minval,maxval)
  296.     int *param;    /* address of parameter to be set */
  297.     int val;    /* value from command line */
  298.     char argtyp;    /* +, -, or 0 */
  299.     int defval;    /* default value */
  300.     int minval;    /* minimum allowable value */
  301.     int maxval;    /* maximum allowable value */
  302.     {
  303.  
  304.     switch( argtyp ) {
  305.       case '+':    *param += val;
  306.             break;
  307.  
  308.       case '-':    *param -= val;
  309.             break;
  310.  
  311.       case '0':    *param = val;
  312.             break;
  313.  
  314.       default:    *param = defval;
  315.       }
  316.     if( *param > maxval )
  317.       *param = maxval;
  318.     if( *param < minval )
  319.       *param = minval;
  320.     }
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327. /*
  328.     Underline
  329.         Replace non-whitespace chars with '_','\b',char
  330. */
  331.  
  332. underl(buf,tbuf,size)
  333.     char buf[];
  334.     char tbuf[];
  335.     int size;
  336.     {
  337.     int i,j;
  338.     char c;
  339.  
  340.     j = 0;
  341.     for( i = 0; buf[i] != '\n' && j < size-1; i++ ) {
  342.       tbuf[j++] = buf[i];
  343.       if( buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\b' ) {
  344.         c = tbuf[--j];
  345.         tbuf[j++] = '_';
  346.         tbuf[j++] = '\b';
  347.         tbuf[j++] = c;
  348.         }
  349.       }
  350.     tbuf[j++] = '\n';
  351.     tbuf[j] = '\0';
  352.     strcpy(buf,tbuf);
  353.     }
  354.  
  355.  
  356.  
  357. /*
  358.     Center -- fakeout by setting temporary indent
  359. */
  360.  
  361. center(buf)
  362.     char *buf;
  363.     {
  364.     int width();
  365.     int temp;
  366.  
  367.     temp = (rmval + tival - width(buf))/2;
  368.     tival = max(temp,0);
  369.     }
  370.  
  371.  
  372. /*
  373.     Spread words to justify right margin
  374. */
  375.  
  376. spread(buf,outp,nextra,outwds)
  377.     char buf[];
  378.     int outp;
  379.     int nextra;
  380.     int outwds;
  381.     {
  382.     int i,j,nb,nholes;
  383.     int kk;
  384.  
  385.     if( nextra <= 0 || outwds <= 1 )
  386.       return;
  387.     dir = ++dir & 1;    /* toggle bias direction */
  388.     nholes = outwds - 1;
  389.     i = outp - 1;    /* point at final non-blank */
  390.     j = min(i + nextra,(MAXOUT-2));
  391.     while( i < j ) {
  392.       buf[j] = buf[i];
  393.       if( buf[i] == ' ' ) {
  394.         if( dir )
  395.           nb = nextra / nholes;        /* truncated */
  396.         else
  397.           nb = (nextra - 1) / nholes + 1;    /* rounded */
  398.         nextra -= nb;
  399.         nholes--;
  400.         for( ; nb > 0; nb-- )
  401.           buf[--j] = ' ';
  402.         }
  403.       --i;
  404.       --j;
  405.       }
  406.     }
  407.  
  408.  
  409.  
  410.  
  411. /*
  412.     put a word in outbuf including margin justification
  413. */
  414.  
  415. putwrd(wrdbuf)
  416.     char *wrdbuf;
  417.     {
  418.     int width();
  419.     int last;
  420.     int llval;
  421.     int nextra;
  422.     int w;
  423.     int i;    /* debug only */
  424.  
  425.     w = width(wrdbuf);    /* printable width of wrdbuf[] */
  426.     last = strlen(wrdbuf) + outp; 
  427.     llval = rmval - tival;    /* printable line length */
  428.     if( outp > 0 && ( (outw+w) > llval || last >= (MAXOUT-2) ) ) {
  429.       last -= outp;                /* too big */
  430.       nextra = llval - (outw - 1);    /* # blanks needed to pad */
  431.       if( nextra > 0 && outwds > 1 ) {
  432.         outp--;            /* back up to final blank */
  433.         spread(outbuf,outp,nextra,outwds);
  434.         outp += nextra;
  435.         }
  436.       brk();    /* flush previous line */
  437.       }
  438.     strcpy(outbuf+outp,wrdbuf);    /* add new word to outbuf[] */
  439.     outp = last;
  440.     outbuf[outp++] = ' ';        /* add a blank behind it */
  441.     outw += (w + 1);        /* update output width */
  442.     outwds++;            /* increment the word count */
  443.     }
  444.  
  445.  
  446.  
  447.  
  448. /*
  449.     brk -- end current filled line
  450. */
  451.  
  452. brk()
  453.     {
  454.  
  455.     if( outp > 0 ) {
  456.       outbuf[outp] = '\n';
  457.       outbuf[++outp] = '\0';
  458.       put(outbuf);
  459.       }
  460.     outp = outw = outwds = 0;
  461.     }
  462.  
  463.  
  464.  
  465. /*
  466.     width of a printed line
  467. */
  468.  
  469. width(buf)
  470.     char *buf;
  471.     {
  472.     int wid;
  473.     char c;
  474.  
  475.     wid = 0;
  476.     while ( c = *buf++ )
  477.       if( c == '\b' )
  478.         wid--;
  479.       else if( c != '\n' )
  480.         wid++;
  481.     return wid;
  482.     }
  483.  
  484.  
  485.  
  486. /*
  487.     expand tabs in the input buffer since
  488.     the word processor doesn't really know how
  489.     to handle them
  490. */
  491.  
  492. xpndtab(inbuf)
  493.     char *inbuf;
  494.     {
  495.     char tbuf[300];
  496.     char *i,*t;
  497.     int col;
  498.     char c;
  499.  
  500.     col = 0;
  501.     i = inbuf;
  502.     t = tbuf;
  503.     while( c=*i++ ) {
  504.       if( c == '\t' )
  505.         do {
  506.           *t++ = ' ';
  507.           } while( ++col & 7 );
  508.       else
  509.         *t++ = c;
  510.       }
  511.     *t = '\0';
  512.     strcpy(inbuf,tbuf);
  513.     }
  514.  
  515.  
  516.